/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include "celpfilt.h"

/**************************************************************************
*
* ROUTINE
*               do_pfilt
*               do_pfilt_dynamic
*
* FUNCTION
*               pole filter - given a filter structure
*               do_pfilt uses static coefficients
*               do_pfilt_dynamic uses changing coefficients
*
* SYNOPSIS
*               subroutine do_pfilt(flt, data)
*               subroutine do_pfilt_dynamic(flt, coef, data)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*       flt             FILTER  i/o     FILTER structure
*       coef            fxpt_16  i      coefficients
*       data            fxpt_16 i/o     input/filtered output data
*
***************************************************************************
*
* DESCRIPTION
*
*       Recursive all-pole in-place time-domain filter.
*       The transfer function 1/A(z) is implemented
*       in a direct form realisation.
*
*                   N       -i
*       H(z) = 1 / SUM a(i)z         with a(0) = +1.0
*                  i=0
*
*       NOTE:  a(0) is not used for the actual computing,
*       as can easily be seen in the following flow graph.
*
*       x(t) ->---+------->--------(z0)-----> y(t)
*                 |                  |
*                 +-------< -a1 ----z1
*                 |                  |
*                 +-------< -a2 ----z2
*                 |                  |
*                 :                  :
*                 |                  |
*                 +-------< -aN ----zN
*
*
***************************************************************************
*
* CALLED BY
*
*       FindAdaptResidual FindLPCResidual UpdateEverything
*       HPF_InSpeech HPF_OutSpeech LPC_Synthesis PostFilter
*
***************************************************************************/

#if 0 /* function now isolated in do_pfilt2.c */
void do_pfilt(
FILTER *flt,
fxpt_32 indata[],       /* 17.14 format */
fxpt_16 outdata[])      /* 15.0  format */
{
        int t, j;

FXPT_PUSHSTATE("do_pfilt", -1.0, -1.0);
        if (flt->coef[0] != 8192) {     /* 1.0 in 2.13 format */
                CELP_PRINTF(("polefilt:  bad coefficients\n"));
                CELP_ABORT ();
        }

        for (t = 0; t < flt->data_length; t++) {
                flt->memory[0] = indata[t];
                /*flt->memory[0] = fxpt_shr32_fast(fxpt_deposit_h(data[t]), 1);*/
                for (j = flt->order; j > 0; j--) {
                        /*flt->memory[0] -= flt->coef[j] * flt->memory[j];*/
//                        flt->memory[0] = fxpt_sub32(flt->memory[0],
//                            fxpt_shl32_fast(fxpt_mult32(flt->coef[j],
//                            fxpt_extract_h(flt->memory[j])), 2));
                        /*flt->memory[0] = fxpt_sub16(flt->memory[0],
                            fxpt_mult16_fix(flt->coef[j], flt->memory[j], 13));*/
                        flt->memory[0] = fxpt_sub32(flt->memory[0],
                            fxpt_mult64_fix( flt->coef[j],
                            flt->memory[j], 14) );
                        flt->memory[j]  = flt->memory[j-1];
                }
                outdata[t] = fxpt_extract_h(fxpt_shl32_fast(flt->memory[0], 3));
        }
FXPT_POPSTATE();
}
#endif


#if 0 /* function now implemented in its own file */
void do_pfilt_dynamic(
FILTER  *flt,
fxpt_16 coef[],         /* 2.13 format */
fxpt_16 data[])         /* 15.0 format */
{
        int t, j;

FXPT_PUSHSTATE("do_pfilt_dynamic", -1.0, -1.0);
        if (coef[0] != 8192) {          /* 1.0 in 2.13 format */
                CELP_PRINTF(("polefilt:  bad coefficients\n"));
                CELP_ABORT();
        }

        for (t = 0; t < flt->data_length; t++) {
                flt->memory[0] = fxpt_shr32_fast(fxpt_deposit_h(data[t]), 1);
                for (j = flt->order; j > 0; j--) {
                        /*flt->memory[0] -= coef[j] * flt->memory[j];*/
                        flt->memory[0] = fxpt_sub32(flt->memory[0],
                            fxpt_shl32_fast(fxpt_mult32(coef[j],
                            fxpt_extract_h(flt->memory[j])), 2));
                        /*flt->memory[0] = fxpt_sub16(flt->memory[0],
                            fxpt_mult16_fix(coef[j], flt->memory[j], 13));*/
                        flt->memory[j]  = flt->memory[j-1];
                }
                data[t] = fxpt_extract_h(fxpt_shl32_fast(flt->memory[0], 1));
        }
FXPT_POPSTATE();
}
#endif


#if 0 /* function now implemented in its own file */
void do_pfilt_dynamic32to16(
FILTER  *flt,
fxpt_16 coef[],         /*  2.13 format */
fxpt_32 indata[],       /* 16.15 format */
fxpt_16 outdata[])      /* 15.0  format */
{
        int t, j;

FXPT_PUSHSTATE("do_pfilt_dynamic32to16", -1.0, -1.0);
        if (coef[0] != 8192) {          /* 1.0 in 2.13 format */
                CELP_PRINTF(("polefilt:  bad coefficients\n"));
                CELP_ABORT ();
        }

        for (t = 0; t < flt->data_length; t++) {
                flt->memory[0] = indata[t];
                for (j = flt->order; j > 0; j--) {
                        /*flt->memory[0] -= coef[j] * flt->memory[j];*/
                        flt->memory[0] = fxpt_sub32(flt->memory[0],
                            fxpt_shl32_fast(fxpt_mult32(coef[j],
                            fxpt_extract_h(flt->memory[j])), 2));
                        flt->memory[j]  = flt->memory[j-1];
                }
                outdata[t] = fxpt_extract_h(fxpt_shl32_fast(flt->memory[0], 1));
        }
FXPT_POPSTATE();
}
#endif
